﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using RebellionII.GameObjects;
using RebellionII.GameObjects.Other;
using RebellionII.GameObjects.Units.Instances;
using RebellionII.GameObjects.Other.Instances;
using RebellionII.GameObjects.Units;
using Microsoft.Xna.Framework.Graphics;


namespace RebellionII.GameObjects.Map
{
    [Flags]
    public enum SystemSpecials
    {
        None = 0,
        FacilityBonus = 1,
        ShipBonus = 2,
        TroopBonus = 4,
        JediBonus = 8,
    }
    public enum SectorType
    {
        Core,
        Mid,
        Rim,
    }


    public class RebSystem 
    {
        #region Fields & Parameters
        public static int startID = 0;
        public int iRebSystemID { get; set; }

        [ContentSerializerIgnore]
        public List<UnitInstance> lTroop = new List<UnitInstance>();

        [ContentSerializerIgnore]
        public List<UnitInstance> lFighter = new List<UnitInstance>();

        [ContentSerializerIgnore]
        public List<MissionInstance> lMission = new List<MissionInstance>();

        [ContentSerializerIgnore]
        public List<Fleet> lFleet = new List<Fleet>();

        [ContentSerializerIgnore]
        public List<Character> lCharacter = new List<Character>();

        [ContentSerializerIgnore]
        public List<UnitInstance> lFacilities = new List<UnitInstance>();

        public List<int> lNeighbours = new List<int>();

        public Vector2 vPosition { get; set; }
        public string sName { get; set; }

        [ContentSerializerIgnore]
        public int iNumFacilities{ get; set; }
        [ContentSerializerIgnore]
        public int iNumEnergy { get; set; }

        public string sTextureName { get; set; }
        public SectorType eSectorType { get; set; }
        public string sSectorName { get; set; }

        public bool bIsKeySystem { get; set; }


        [ContentSerializerIgnore]
        public int iLoyaltyEmpire {get; set;}
        [ContentSerializerIgnore]
        public int iLoyaltyAlliance{get; set;}
        [ContentSerializerIgnore]
        public int iLoyaltySystem{get; set;}
        [ContentSerializerIgnore]
        public bool bIsVisible{ get; set; }
        [ContentSerializer]
        public TeamName AssignTo { get; set; }
        [ContentSerializerIgnore]
        public TeamName CurrentOwner { get; set; }
        public SystemSpecials eSpecials { get; set; }

        public Color TeamColor
        {
            get
            {
                if (CurrentOwner == TeamName.Alliance)
                    return Color.Red;
                if (CurrentOwner == TeamName.Empire)
                    return Color.LimeGreen;
                if (CurrentOwner == TeamName.Hutts)
                    return Color.Goldenrod;
                if (CurrentOwner == TeamName.Smugglers)
                    return Color.BlueViolet;
                else
                    return Color.RoyalBlue;
            }

        }

        [ContentSerializerIgnore]
        public int ShipBuildReferenceID { get; set; }
        [ContentSerializerIgnore]
        public int ShipBuildQuantity { get; set; }
        [ContentSerializerIgnore]
        public int ShipBuildCurrentProgress { get; set; }
        [ContentSerializerIgnore]
        public int ShipBuildOverflow { get; set; }
        [ContentSerializerIgnore]
        public int ShipBuildDestinationID { get; set; }
        [ContentSerializerIgnore]
        public int ShipBuildTotalCost { get; set; }
        [ContentSerializerIgnore]
        public bool bJustBuiltShip { get; set; }

        [ContentSerializerIgnore]
        public int TroopBuildReferenceID { get; set; }
        [ContentSerializerIgnore]
        public int TroopBuildQuantity { get; set; }
        [ContentSerializerIgnore]
        public int TroopBuildCurrentProgress { get; set; }
        [ContentSerializerIgnore]
        public int TroopBuildOverflow { get;  set; }
        [ContentSerializerIgnore]
        public int TroopBuildDestinationID { get;set; }
        [ContentSerializerIgnore]
        public int TroopBuildTotalCost { get; set; }
        [ContentSerializerIgnore]
        public bool bJustBuiltTroop { get; set; }

        [ContentSerializerIgnore]
        public int FacilityBuildReferenceID { get; set; }
        [ContentSerializerIgnore]
        public int FacilityBuildQuantity { get; set; }
        [ContentSerializerIgnore]
        public int FacilityBuildCurrentProgress { get; set; }
        [ContentSerializerIgnore]
        public int FacilityBuildOverflow { get;  set; }
        [ContentSerializerIgnore]
        public int FacilityBuildDestinationID { get;  set; }
        [ContentSerializerIgnore]
        public int FacilityBuildTotalCost { get; set; }
        [ContentSerializerIgnore]
        public bool bJustBuiltFacility { get; set; }
        #endregion

        public RebSystem()
        {
            iRebSystemID = startID;
            startID++;
            CurrentOwner = TeamName.Default;
        }

        /// <summary>
        /// Strictly used for creating a planet in the PlanetEditor. All planets should be loaded in via the XML files for actual gameplay.
        /// </summary>
        public RebSystem(Vector2 position, string name, string texture,
            SectorType eType, string sectorname, bool keysystem, SystemSpecials specials, TeamName assignto)
        {
            iRebSystemID = startID;
            startID++;
            vPosition = position;
            sName = name;
            sTextureName = texture;
            eSectorType = eType;
            bIsKeySystem = keysystem;
            eSpecials = specials;
            sSectorName = sectorname;
            AssignTo = assignto;
            CurrentOwner = TeamName.Default;
        }

        /// <summary>
        /// Used to increase the diplomacy for a team a certain amount
        /// </summary>
        /// <param name="eTeamName">Which Team wants to increase their diplomacy</param>
        /// <param name="amount">Percent out of 100 to increase this</param>
        public void IncreaseDiplomacy(TeamName eTeamName, int amount)
        {
            int iRemainder = amount % 2;
            amount -= iRemainder;
            switch (eTeamName)
            {
                case TeamName.Alliance:
                    iLoyaltyEmpire -= amount / 2;
                    if (iLoyaltyEmpire < 0)
                    {
                        int iAdd = 0 - iLoyaltyEmpire;
                        iLoyaltyEmpire = 0;
                        iLoyaltyAlliance -= iAdd;
                    }
                    iLoyaltyAlliance += amount / 2;
                    iLoyaltySystem -= amount / 2;
                    break;
                case TeamName.Empire:
                    iLoyaltyAlliance -= amount / 2;
                    if (iLoyaltyAlliance < 0)
                    {
                        int iAdd = 0 - iLoyaltyAlliance;
                        iLoyaltyAlliance = 0;
                        iLoyaltyEmpire -= iAdd;
                    }
                    iLoyaltyEmpire += amount / 2;
                    iLoyaltySystem -= amount / 2;
                    break;
                case TeamName.Default:
                    iLoyaltyAlliance -= amount / 2;
                    iLoyaltyEmpire -= amount / 2;
                    if (iLoyaltyAlliance < 0)
                    {
                        int iAdd = 0 - iLoyaltyAlliance;
                        iLoyaltySystem += iAdd;
                        iLoyaltyAlliance = 0;
                    }
                    if (iLoyaltyEmpire < 0)
                    {
                        int iAdd = 0 - iLoyaltyAlliance;
                        iLoyaltySystem += iAdd;
                        iLoyaltyEmpire = 0;
                    }
 
                    break;
                default:
                    throw new NotImplementedException("Stop using broken stuff. Check Rebsystem and what calls increasediplomacy");
            }
        }
        /// <summary>
        /// Used to Set a percent of diplomacy for a team
        /// </summary>
        /// <param name="eTeamName">The Team to set</param>
        /// <param name="amount">The percentage to set it to</param>
        public void SetDiplomacy(TeamName eTeamName, int amount)
        {
            int iRemainder = amount % 2;
            amount -= iRemainder;
            CurrentOwner = eTeamName;
            switch (eTeamName)
            {
                case TeamName.Alliance:
                    iLoyaltyAlliance = amount;
                    iLoyaltySystem = ((100 - amount) / 2);
                    iLoyaltyEmpire = ((100 - amount) / 2);
                    break;
                case TeamName.Empire:
                    iLoyaltyEmpire = amount;
                    iLoyaltySystem = ((100 - amount) / 2);
                    iLoyaltyAlliance = ((100 - amount) / 2);
                    break;
                default:
                    iLoyaltySystem = amount;
                    iLoyaltyAlliance = ((100 - amount) / 2);
                    iLoyaltyEmpire = ((100 - amount) / 2);
                    break;
            }
        }

        public TeamName GetOwner()
        {
            if (iLoyaltyAlliance > 60)
                return TeamName.Alliance;
            if (iLoyaltyEmpire > 60)
                return TeamName.Empire;
            else
            {
                return AssignTo;
            }
        }

        /// <summary>
        /// Build a Ship in the Shipyard
        /// </summary>
        /// <param name="referenceID">The Unit to Build</param>
        /// <param name="quantity">The Amount</param>
        /// <param name="prod">The Units Cost to Build</param>
        public void BuildShips(int referenceID, int quantity, int prod)
        {
            ShipBuildReferenceID = referenceID;
            ShipBuildQuantity = quantity;
            ShipBuildDestinationID = iRebSystemID;
            ShipBuildTotalCost = prod;
        }
        /// <summary>
        /// Build a Ship in the Shipyard
        /// </summary>
        /// <param name="referenceID">The Unit to Build</param>
        /// <param name="quantity">The Amount</param>
        /// <param name="prod">The Units Cost to Build</param>
        /// <param name="systemID">The System to send the Unit to</param>
        public void BuildShips(int referenceID, int quantity, int prod ,int systemID )
        {
            ShipBuildReferenceID = referenceID;
            ShipBuildQuantity = quantity;
            ShipBuildDestinationID = systemID;
            ShipBuildTotalCost = prod;
        }

        /// <summary>
        /// Build a Troop in the Barracks
        /// </summary>
        /// <param name="referenceID">The Unit to Build</param>
        /// <param name="quantity">The Amount</param>
        /// <param name="prod">The Units Cost to Build</param>
        public void BuildTroops(int referenceID, int quantity, int prod)
        {
            TroopBuildReferenceID = referenceID;
            TroopBuildQuantity = quantity;
            TroopBuildDestinationID = iRebSystemID;
            TroopBuildTotalCost = prod;
        }
        /// <summary>
        /// Build a Troop in the Barracks
        /// </summary>
        /// <param name="referenceID">The Unit to Build</param>
        /// <param name="quantity">The Amount</param>
        /// <param name="prod">The Units Cost to Build</param>
        /// <param name="systemID">The System to send the Unit to</param>
        public void BuildTroops(int referenceID, int quantity, int prod, int systemID)
        {
            TroopBuildReferenceID = referenceID;
            TroopBuildQuantity = quantity;
            TroopBuildDestinationID = systemID;
            TroopBuildTotalCost = prod;
        }

        /// <summary>
        /// Build a Building in the Construction Yard
        /// </summary>
        /// <param name="referenceID">The Unit to Build</param>
        /// <param name="quantity">The Amount</param>
        /// <param name="prod">The Units Cost to Build</param>
        public void BuildFacilties(int referenceID, int quantity, int prod)
        {
            FacilityBuildReferenceID = referenceID;
            FacilityBuildQuantity = quantity;
            FacilityBuildDestinationID = iRebSystemID;
            FacilityBuildTotalCost = prod;
        }
        /// <summary>
        /// Build a Building in the Construction Yard
        /// </summary>
        /// <param name="referenceID">The Unit to Build</param>
        /// <param name="quantity">The Amount</param>
        /// <param name="prod">The Units Cost to Build</param>
        /// <param name="systemID">The System to send the Unit to</param>
        public void BuildFacilties(int referenceID, int quantity, int prod, int systemID)
        {
            FacilityBuildReferenceID = referenceID;
            FacilityBuildQuantity = quantity;
            FacilityBuildDestinationID = systemID;
            FacilityBuildTotalCost = prod;
        }

        /// <summary>
        /// Clear The Current Build
        /// </summary>
        public void ClearShipBuild()
        {
            ShipBuildCurrentProgress = 0;
            ShipBuildOverflow = 0;
            ShipBuildQuantity = 0;
            ShipBuildReferenceID = 0;
            ShipBuildDestinationID = 0;
            ShipBuildTotalCost = 0;
        }
        /// <summary>
        /// Clear The Current Build
        /// </summary>
        public void ClearTroopBuild()
        {
            TroopBuildCurrentProgress = 0;
            TroopBuildOverflow = 0;
            TroopBuildQuantity = 0;
            TroopBuildReferenceID = 0;
            TroopBuildDestinationID = 0;
            TroopBuildTotalCost = 0;
        }
        /// <summary>
        /// Clear The Current Build
        /// </summary>
        public void ClearFacilityBuild()
        {
            FacilityBuildCurrentProgress = 0;
            FacilityBuildOverflow = 0;
            FacilityBuildQuantity = 0;
            FacilityBuildReferenceID = 0;
            FacilityBuildDestinationID = 0;
            FacilityBuildTotalCost = 0;
        }
   }
}
